/// @Classname : HcImage
/// @Author :
/// @Time : 2023-04-20 9:06
/// @Description : 通用的图片加载组件
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:hc_ui/config/hc_customer_config.dart';
import 'package:hc_ui/constants/hc_size.dart';
import 'package:hc_ui/utils/hc_file_util.dart';

import '../../constants/hc_color.dart';

///图片加载出错的构建函数
/// 本地图片构建出错返回堆栈信息 网络图片返回网络路径
typedef ImageErrorBuilder = Widget Function(
  BuildContext context,
  dynamic error,
  dynamic url,
);

class HcImage extends StatelessWidget {
  //图片地址
  final String src;

  //图片出错的占位符
  final ImageErrorBuilder? errorBuilder;

  //加载中的占位符
  final ProgressIndicatorBuilder? loadingBuilder;

  //请求图片的标题头
  final Map<String, String>? httpHeader;

  ///高度
  final double? height;

  ///宽度
  final double? width;

  ///图片的 Fit
  final BoxFit? fit;

  ///图片质量
  final FilterQuality? filterQuality;

  //图片混合颜色
  final Color? color;

  /// 混合模式
  final BlendMode? colorBlendMode;

  /// 对齐方式 默认居中
  final Alignment alignment;

  //是否重复
  final ImageRepeat repeat;

  //图片的圆角
  final BorderRadius? borderRadius;

  const HcImage({
    super.key,
    required this.src,
    this.errorBuilder,
    this.loadingBuilder,
    this.httpHeader,
    this.height,
    this.width,
    this.fit,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.filterQuality = FilterQuality.low,
    this.color,
    this.colorBlendMode,
    this.borderRadius,
  });

  HcImage.circle({
    super.key,
    required this.src,
    this.errorBuilder,
    this.loadingBuilder,
    this.httpHeader,
    required double size,
    this.filterQuality,
    this.color,
    this.colorBlendMode,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
  })  : width = size,
        height = size,
        borderRadius = BorderRadius.circular(size / 2),
        fit = BoxFit.cover;

  @override
  Widget build(BuildContext context) {
    // 获取图片的信息
    Map<String, dynamic> imageInfo = HCFileUtil.checkAndFixImagePath(src);
    //图片的照片属性
    HcImageType type = imageInfo['type'];
    //图片的路径
    String imageUrl = imageInfo['url'];
    //本地图片展示的Provider;
    ImageProvider? imageProvider;
    switch (type) {
      case HcImageType.assets:
        imageProvider = AssetImage(imageUrl);
        break;
      case HcImageType.file:
        imageProvider = FileImage(File(imageUrl));
        break;
      case HcImageType.base64:
        Uint8List bytes = const Base64Decoder().convert(imageUrl);
        imageProvider = MemoryImage(bytes);
        break;
      case HcImageType.network:
        imageProvider = null;
        break;
    }
    //夜间模式增加遮罩 日间模式不增加
    Color maskColor = HcCustomerConfig().hcImageConfig.enableDarkMode &&
            HcCustomerConfig().themeMode == ThemeMode.dark
        ? HcCustomerConfig().hcImageConfig.maskColor
        : Colors.white;
    return ClipRRect(
      borderRadius:
          borderRadius ?? HcCustomerConfig().hcImageConfig.borderRadius,
      child: ShaderMask(
        shaderCallback: (Rect bounds) {
          return LinearGradient(colors: [maskColor, maskColor])
              .createShader(bounds);
        },
        child: imageProvider != null
            ? Image(
                image: imageProvider,
                width: width,
                height: height,
                fit: fit,
                color: color,
                alignment: alignment,
                repeat: repeat,
                colorBlendMode: colorBlendMode,
                filterQuality: filterQuality ??
                    HcCustomerConfig().hcImageConfig.filterQuality,
                errorBuilder: (context, error, stackTrace) =>
                    _imageErrorBuilder(context, error, stackTrace),
              )
            : CachedNetworkImage(
                imageUrl: imageUrl,
                width: width,
                height: height,
                httpHeaders:
                    httpHeader ?? HcCustomerConfig().hcImageConfig.httpHeader,
                fit: fit,
                color: color,
                alignment: alignment,
                repeat: repeat,
                colorBlendMode: colorBlendMode,
                filterQuality: filterQuality ??
                    HcCustomerConfig().hcImageConfig.filterQuality,
                fadeOutCurve: HcCustomerConfig().hcImageConfig.fadeOutCurve,
                fadeInCurve: HcCustomerConfig().hcImageConfig.fadeInCurve,
                fadeOutDuration:
                    HcCustomerConfig().hcImageConfig.fadeOutDuration,
                fadeInDuration: HcCustomerConfig().hcImageConfig.fadeInDuration,
                errorWidget: (context, url, error) =>
                    _imageErrorBuilder(context, error, url),
                progressIndicatorBuilder: (context, url, progress) =>
                    _imageLoadingBuilder(context, url, progress),
              ),
      ),
    );
  }

  ///图片加载出错的方法
  Widget _imageErrorBuilder(BuildContext context, dynamic error, dynamic url) {
    if (errorBuilder != null) {
      return errorBuilder!(context, error, url);
    }
    if (HcCustomerConfig().hcImageConfig.errorBuilder != null) {
      return HcCustomerConfig().hcImageConfig.errorBuilder!(
          context, error, url);
    }
    return Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.zero,
          color: HcColor.imagePlaceholderColor.withOpacity(0.7),
        ),
        padding: const EdgeInsets.all(HcSize.defaultPadding),
        child: const Center(
            child: Icon(Icons.error_outline,
                size: HcFont.f32, color: HcColor.imagePlaceholderIconColor)));
  }

  ///图片加载中的方法
  Widget _imageLoadingBuilder(context, url, progress) {
    if (loadingBuilder != null) {
      return loadingBuilder!(context, url, progress);
    }
    if (HcCustomerConfig().hcImageConfig.loadingBuilder != null) {
      return HcCustomerConfig().hcImageConfig.loadingBuilder!(
          context, url, progress);
    }
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.zero,
        color: HcColor.imagePlaceholderColor.withOpacity(0.5),
      ),
      padding: const EdgeInsets.all(HcSize.defaultPadding),
      child: const AspectRatio(
        aspectRatio: 1 / 1,
        child: CircularProgressIndicator(),
      ),
    );
  }
}
